﻿using System;
using System.Collections.Generic;
////using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Drawing;
using System.Windows.Forms;
using Fireball.Windows.Forms;
using Fireball.Syntax;
using Fireball.CodeEditor.SyntaxFiles;
using DBConnectionLib;


namespace DBSourceToolsLib.SysObjects
{
    public class SOView : SysObject//, Interfaces.IDisplayPanel
    {
        protected DataSets.TableColumnsDS m_oColumnListDs = new DBSourceToolsLib.DataSets.TableColumnsDS();

        public SOView(string strName, string strBaseDirectory, Database oDatabase, string strUrn)
            : base(strName, strBaseDirectory, oDatabase, SysObjectType.View)
        {
            this.Urn = strUrn;
            //LoadScript(oDatabase);
        }
        public SOView(string strFileName, Database oDatabase)
            : base(SysObjectType.View, strFileName, oDatabase)
        {
            // we are loading this from disk - ensure we load columns from disk as well.
            string strColFileName = this.BaseDirectory + "\\Views\\Columns\\" + this.Name + "_Columns.xml";
            if (System.IO.File.Exists(strColFileName))
                this.m_oColumnListDs.ReadXml(strColFileName);

        }

        public SOView(SysObject oldSysObject, Database targetDatabase)
            :base ( oldSysObject.Name, targetDatabase.BaseDirectory, targetDatabase, SysObjectType.View)
        {
            this.Text = oldSysObject.Text;
            this.Text = this.Text.Replace("[" + oldSysObject.DBName + "]", "[" + targetDatabase.DatabaseName + "]");
        }


        public override void LoadScript(Database oDatabase, string strOutputFileName)
        {

        }



        #region IDisplayPanel Members

        public override System.Windows.Forms.Panel GetPanel()
        {
            Panel oPanel = new Panel();
            oPanel.Dock = DockStyle.Fill;

            CodeEditorControl codeEdit = new CodeEditorControl();
            codeEdit.Dock = DockStyle.Fill;

            CodeEditorSyntaxLoader.SetSyntax(codeEdit, SyntaxLanguage.SqlServer2K);
            codeEdit.Document.Text = this.Text;
            oPanel.Controls.Add(codeEdit);

            return oPanel;
        }

        #endregion

        internal void LoadScript(Database oDatabase, string strOutputFileName, Microsoft.SqlServer.Management.Smo.View oSmo)
        {
            base.EnsureDirectoryExists(strOutputFileName);

            Microsoft.SqlServer.Management.Smo.ScriptingOptions oScriptingOptions = new Microsoft.SqlServer.Management.Smo.ScriptingOptions();
            oScriptingOptions.ClusteredIndexes = false;
            oScriptingOptions.NonClusteredIndexes = false;
            oScriptingOptions.DriAll = true;
            oScriptingOptions.Indexes = false;
            oScriptingOptions.IncludeDatabaseContext = false;
            oScriptingOptions.ScriptDrops = true;
            oScriptingOptions.IncludeIfNotExists = true;
            //oScriptingOptions.ExtendedProperties = true;
            oScriptingOptions.FileName = strOutputFileName;
            oScriptingOptions.ExtendedProperties = UserSettings.Instance().UseExtendedProperties;
            oScriptingOptions.AnsiFile = UserSettings.Instance().UseANSII;

            StringCollection strDropColl = new StringCollection();
            strDropColl = oSmo.Script(oScriptingOptions);
            oScriptingOptions.ScriptDrops = false;
            oScriptingOptions.IncludeIfNotExists = false;
            StringCollection myStrColl = new StringCollection();
            myStrColl = oSmo.Script(oScriptingOptions);

            foreach (Microsoft.SqlServer.Management.Smo.Index myIndex in oSmo.Indexes)
            {
                Microsoft.SqlServer.Management.Smo.ScriptingOptions indexScriptingOptions = new Microsoft.SqlServer.Management.Smo.ScriptingOptions();
                indexScriptingOptions.DriAll = true;
                indexScriptingOptions.IncludeDatabaseContext = false;
                indexScriptingOptions.ExtendedProperties = UserSettings.Instance().UseExtendedProperties;
                indexScriptingOptions.AnsiFile = UserSettings.Instance().UseANSII;

                StringCollection indexStrColl = new StringCollection();
                indexStrColl = myIndex.Script(indexScriptingOptions);
                //myStrColl.AddRange(indexStrColl);
                foreach (string indexString in indexStrColl)
                {
                    myStrColl.Add(indexString);
                }
            }
            base.AddDropScriptToFile(strOutputFileName, strDropColl);
            base.SetTextFromFile(strOutputFileName);

            this.m_oColumnListDs.TableColumns.Clear();

            foreach (Microsoft.SqlServer.Management.Smo.Column oCol in oSmo.Columns)
            {
                //foreach (Microsoft.SqlServer.Management.Smo.Property oProp in oCol.Properties)
                //{
                //    HCSocketToolsLib.HCSocketSender.Instance().SendUDPMessage(
                //        System.Reflection.MethodBase.GetCurrentMethod()
                //        , String.Format("{0} {1}", oProp.Name, oProp.Value));

                //}
                DataSets.TableColumnsDS.TableColumnsRow newRow = m_oColumnListDs.TableColumns.NewTableColumnsRow();
                
                newRow.ColumnName = oCol.Name;
                newRow.isComputed = oCol.Computed;
                newRow.inPrimaryKey = oCol.InPrimaryKey;
                newRow.Type = oCol.DataType.ToString();
                m_oColumnListDs.TableColumns.AddTableColumnsRow(newRow);
            }
            m_oColumnListDs.AcceptChanges();

            string strColumnsFile = strOutputFileName.Substring(0, strOutputFileName.LastIndexOf("\\") + 1);
            strColumnsFile += "Columns\\" + this.Name + "_Columns.xml";
            base.EnsureDirectoryExists(strColumnsFile);
            FileUtils.EnsureFileIsWriteable(strColumnsFile);
            m_oColumnListDs.WriteXml(strColumnsFile);


        }
         
        public override List<ColInfo> Columns
        {
            get
            {
                List<ColInfo> strList = new List<ColInfo>();
                foreach (DBSourceToolsLib.DataSets.TableColumnsDS.TableColumnsRow oRow in
                    this.m_oColumnListDs.TableColumns.Rows)
                {
                    ColInfo oInfo = new ColInfo();
                    oInfo.Name = oRow.ColumnName;
                    oInfo.Type = oRow.Type;
                    oInfo.PrimaryKey = oRow.inPrimaryKey;
                    strList.Add(oInfo);
                }
                return strList;
            }
        }

        public string GetSelectQuery()
        {
            StringBuilder oBuilder = new StringBuilder();
            oBuilder.AppendLine("select ");
            //string strQuery = "select ";//[" + this.Name + "]";
            bool isFirstCol = true;

            foreach (DBSourceToolsLib.DataSets.TableColumnsDS.TableColumnsRow row in
                this.m_oColumnListDs.TableColumns.Rows)
            {
                    if (isFirstCol)
                    {
                        oBuilder.AppendLine("\t[" + row.ColumnName + "] ");
                        isFirstCol = false;
                    }
                    else
                    {
                        oBuilder.AppendLine("\t,[" + row.ColumnName + "]");
                    }
            }
            oBuilder.AppendLine("from ");
            oBuilder.AppendLine("\t" + GetFullyQualifiedName());

            return oBuilder.ToString();
        }


        public override DBSourceToolsLib.Composite.DBComposite GetDBComposite()
        {
            Composite.DBComposite oTableComposite = 
                new Composite.DBComposite(this.Name,this.NameNoSchema, 
                    Composite.DBCompositeType.View,
                    new Composite.TreeNodeTag(this.m_Database.NickName,
                "File", this.FileName, this.QualifiedName));

            Composite.DBComposite oDataComposite =
                new Composite.DBComposite("Data","Data",
                    Composite.DBCompositeType.Data,
                    new Composite.TreeNodeTag(this.m_Database.NickName,
                    "Data", this.Name, this.QualifiedName));
            oTableComposite.Add(oDataComposite);

            Composite.DBComposite oFieldsComposite =
                new Composite.DBComposite("Fields","Fields",
                    Composite.DBCompositeType.Fields,
                    new Composite.TreeNodeTag(this.m_Database.NickName,
                    "Fields", this.Name, this.QualifiedName));

            oTableComposite.Add(oFieldsComposite);

            foreach (ColInfo oColInfo in this.Columns)
            {
                Composite.DBComposite oField = new Composite.DBComposite(oColInfo.NameAndType,oColInfo.Name,
                    Composite.DBCompositeType.Field,
                    new Composite.TreeNodeTag(this.m_Database.NickName,
                "Column", oColInfo.Name, null));
                oFieldsComposite.Add(oField);
            }
            return oTableComposite;

        }

    }
}
